﻿// ===============================================================
#define MODEL_NAME_LENGTH		20
#define COMMENT_LENGTH			256
#define ELEMENT_NAME_LENGTH		20

#define UVMAP_NAME			"Texture"
#define NORMALMAP_NAME		"PMDNormal"
#define EDGELINE_NAME		"PMDEdgeLine"

#define PTAG_PMDB	LWID_('P','M','D','B')		// bone param
//	"%hd %hu %u %hu", boneElement[].parentIdx, boneElement[].tipIdx, boneElement[].type, boneElement[].refIdx
#define PTAG_PMDK	LWID_('P','M','D','K')		// ik param
//	"%hu %hu %u %hu %f", ikElement[].rootBoneIdx, ikElement[].tipBoneIdx, ikElement[].boneNum, ikElement[].param, ikElement[].paramF
#define PTAG_PMDI	LWID_('P','M','D','I')		// ik chain boneIdxList(16進)
//	"%04X ...", ikElement[].boneIdxs[n],...
#define PTAG_PMDX	LWID_('P','M','D','X')		// lw pol index(16進) lw側管理用
//	"%04X", boneIndex

#define BTYPE_ROT		0	// 通常(回転)
#define BTYPE_MOV		1	// 通常(回転/移動)
#define BTYPE_CTL		2	// IK Ctl(回転/移動)
#define BTYPE_SEL		3	// 非表示/選択可
#define BTYPE_CHAIN		4	// IK Chain(回転)
#define BTYPE_REF		5	// 回転参照(Refer Indexに倣う)
#define BTYPE_GOAL		6	// IK Goal
#define BTYPE_UNSEL		7	// 非表示/選択不可

// ===============================================================
#pragma pack(1)		// アライメント禁止

#define		PNT_ELEMENT_SIZE	38
typedef struct _pntElement{		// 38 byte 固定
	float pos[3];			// 頂点座標
	float norm[3];			// 頂点ノーマル
	float uv[2];			// ＵＶ
	u_short boneIdx[2];		// ボーンindex
	u_char wgt;				// boneIdx[0]のウェイト値
	u_char eFlag;			// エッジライン描画フラグ(0:有り,1:無し)
} pntElement;

// polElement は u_shortの配列

#define		SURF_ELEMENT_SIZE	70
typedef struct _surfElement{	// 70 byte 固定
	float colrVal[3];		// 基本色
	float tranVal;			// 不透明度
	float glosVal;			// グロス
	float specVal[3];		// スペキュラカラー
	float ambiVal[3];		// アンビエントカラー
	u_char shade_No;		// シェーディング用イメージNo.
	u_char edgeLine;		// エッジライン描画フラグ(0:無し,1:有り)。1に固定しpntElement.eFlagでの指定を推奨
	u_int nPols;			// 割り当てるポリゴン数(三角ポリでのエッジ数なので1/3するとポリゴン数になる)
	char textFileName[20];	// イメージテクスチャ名
} surfElement;

#define		BONE_ELEMENT_SIZE	39
typedef struct _boneElement{	// 39 byte 固定
	char name[ELEMENT_NAME_LENGTH];		// 名前
	short parentIdx;	// 親index(-1:無し)			(tag:PMDB)
	u_short tipIdx;		// 先端座標になるボーンindex(tag:PMDB)
	u_char type;		// ボーンタイプ				(tag:PMDB)
	u_short refIdx;		// 参照ボーンindex			(tag:PMDB)
	float pos[3];
} boneElement;

#define		IK_ELEMENT_SIZE		11
typedef struct _ikElement{	// 11 byte+ 不定
	u_short rootBoneIdx;	// 制御用ボーンindex		(tag:PMDK)
	u_short tipBoneIdx;		// IKゴールボーンindex		(tag:PMDK)
	u_char boneNum;			// IKチェーンの構成ボーン数	(tag:PMDK)
	u_short param;			// パラメータ				(tag:PMDK)
	float paramF;			// パラメータ				(tag:PMDK)
	u_short *boneIdxs;		// IKチェーンを構成するボーンindex	(tag:PMDI)
} ikElement;

#define		SKINPNT_ELEMENT_SIZE		16
typedef struct _skinPntElement{		// 16 byte 固定
	u_int	destPntIdx;				// 頂点index("base"時はpntElement[]に対するindex。他はskinElement[0].skinPntElm[]に対するindex)
	float	pos[3];					// 頂点座標("base"時はpntElement[].pos。他はpntElement[].posに対する相対値。)
} skinPntElement;

#define		SKIN_ELEMENT_SIZE		25
typedef struct _skinElement{		// 25 byte+ 不定
	char name[ELEMENT_NAME_LENGTH];	// モーフ名称(モーフが有る場合、skinElement[0]は"base"が予約)
	u_int pntNum;					// 対象頂点数
	u_char grp;						// UI上のグループNo.(0:予約、1-4)
	skinPntElement *skinPntElm;
} skinElement;

// treeSkinIndexs は u_shortの配列

#define		TREE_R_ELEMENT_SIZE		50
typedef struct _treeRootElement{	// 50 byte
	char name[TREE_R_ELEMENT_SIZE];		// UI上のリストビュー用親階層文字列
} treeRootElement;

#define		TREE_C_ELEMENT_SIZE		3
typedef struct _treeChildElement{	// 3 byte
	u_short boneIdx;		// boneElementのindex
	u_char treeRootIdx;		// treeRootElement[]のindex
} treeChildElement;

typedef struct _Pmd_Header{		// 283(3 + 4 + 20 + 256) byte
	char head[3];						// ヘッダ"Pmd"
	float version;						// バージョン(1.0)
	char modelName[MODEL_NAME_LENGTH];	// モデル名
	char comment[COMMENT_LENGTH];		// コメント
} Pmd_Header;

#pragma pack()		// アライメント禁止解除
// ===============================================================

typedef struct _Pmd_Data{
	pntElement *pntElm;		// 頂点要素
	u_short *polElm;		// ポリゴン要素
	surfElement *surfElm;	// 材質要素
	boneElement *boneElm;	// ボーン要素
	ikElement *ikElm;		// IK要素
	skinElement *skinElm;	// モーフ要素
	u_short *treeSkinIdxs;	// Tree表示用、モーフindex
	treeRootElement *treeRootNames;		// Tree表示用、親階層名
	treeChildElement *treeChildElm;		// Tree表示用、ボーンindex
	u_int pntElmNum;		// 頂点数
	u_int polElmNum;		// ポリゴン数(三角ポリでのエッジ数なので1/3するとポリゴン数になる)
	u_int surfElmNum;		// 材質数
	u_int treeChildNum;		// Tree表示用、ボーン数
	u_short boneElmNum;		// ボーン数
	u_short ikElmNum;		// IKチェーン数
	u_short skinElmNum;		// モーフ数(無い場合は0、有る場合に必要になる"base"も数に含む)
	u_char treeSkinNum;		// Tree表示用、表情としてリストする数
	u_char treeRootNum;		// Tree表示用、親階層数
} Pmd_Data;

// ===============================================================
